package cn.wsn2018.tools.dao.impl;


import cn.wsn2018.tools.common.CommonValue;
import cn.wsn2018.tools.dao.UserDao;
import cn.wsn2018.tools.model.User;
import cn.wsn2018.tools.util.DateUtil;
import cn.wsn2018.tools.util.EncryptUtil;
import cn.wsn2018.tools.util.StringUtil;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import static org.apache.tomcat.jni.Time.now;

/**
 * Created by NZX on 2018/12/11.
 */
@Repository("userDao")
public class UserDaoImpl implements UserDao{
    private Logger logger = Logger.getLogger(UserDaoImpl.class.getName());
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public List<User> listAllUsers(String pageNum,String pageSize) {
        Query query = new Query();
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        int num = Integer.parseInt(pageNum);
        int size = Integer.parseInt(pageSize);
        query.skip((num-1)*size).limit(size);
        List<User> userList = mongoTemplate.find(query,User.class,"user");
        return userList;
    }

    @Override
    public List<User> listUsersByRole(String role,String pageNum,String pageSize) {
        Query query = new Query();
        query.addCriteria(Criteria.where("role").is(role));
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        int num = Integer.parseInt(pageNum);
        int size = Integer.parseInt(pageSize);
        query.skip((num-1)*size).limit(size);
        List<User> userList = mongoTemplate.find(query,User.class,"user");
        return userList;
    }

    @Override
    public User getUserByName(String username) {
        Query query = new Query();
        query.addCriteria(Criteria.where("username").is(username));
        User user = mongoTemplate.findOne(query,User.class,"user");
        return user;
    }

    /**
     * 插入用户
     * @param user
     * @return
     */
    @Override
    public boolean saveUser(User user) {
        JSONObject result = JSONObject.fromObject(mongoTemplate.insert(user,"user"));
        String id = result.optString("id");
        if(id!=null&&!"".equals(id)) {
            //logger.info(result.toString());
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * 删除用户，dao成功返回{"deletedCount":1}
     * @param username
     * @return
     */
    @Override
    public boolean deleteUser(String username) {
        User user = new User();
        user.setUsername(username);
        Query query = new Query();
        query.addCriteria(Criteria.where("username").is(username));
        JSONObject result = JSONObject.fromObject(mongoTemplate.remove(query,User.class,"user"));
        String count = result.optString("deletedCount");
        if(count!=null&&"1".equals(count)){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 修改用户  {"matchedCount":1,"modifiedCount":1,"modifiedCountAvailable":true,"upsertedId":null}
     * @param user
     * @return
     */
    @Override
    public boolean updateUser(String formerName,User user) {
        Query query = new Query();
        query.addCriteria(Criteria.where("username").is(formerName));
        Update update = new Update();
        update.set("username",user.getUsername())
                .set("password",user.getPassword())
                .set("role",user.getRole()).set("pwdUpdateTime",DateUtil.dateToString(new Date()));
        JSONObject result = JSONObject.fromObject(mongoTemplate.upsert(query,update,"user"));
        String count = result.optString("modifiedCount");
        if(count!=null&&"1".equals(count)){
            return true;
        }else {
            return false;
        }
    }

    /**************************************************************************************************************************/
    @Override
    public List<User> listSecUsers(String pageNum, String pageSize, String role, String type, String state,String username,
                                   String lock,String permission) {
        /**
        * @Description:  分页查询所有人，包括已注销的用户
        * @Param: [pageNum, pageSize, role, type, state, username]
        * @return: java.util.List<cn.wsn2018.tools.model.User>
        * @Author: SongDaisong
        * @Date:  2020/1/21 20:09
        */
        Query query = new Query();
        conditionQuery(query,role,type,state,username,lock,permission);
        //排序
       // query.with(new Sort(Sort.Direction.DESC,"lastTime"));
        query.with(
                Sort.by(
                        Sort.Order.desc("state"),       //按用户账号状态排序，state：2-1-0
                        Sort.Order.desc("lastTime"),    //先按用户最后登录时间排序
                        Sort.Order.desc("lock"),
                        Sort.Order.asc("permission")
                )
        );
        query.skip((Integer.parseInt(pageNum)-1)*Integer.parseInt(pageSize)).limit(Integer.parseInt(pageSize));
        List<User> users = mongoTemplate.find(query, User.class, "user");
        return users;
    }

    @Override
    public Long countSecUsers(String role, String type, String state, String username,
                              String lock,String permission) {
        /** 
        * @Description: 统计符合条件的用户数量
        * @Param: [role, type, state, username] 
        * @return: java.lang.Long 
        * @Author: SongDaisong 
        * @Date:  2020/2/6 17:19
        */ 
        Query query = new Query();
        conditionQuery(query,role,type,state,username,lock,permission);
        long cout = mongoTemplate.count(query, "user");
        return cout;
    }

    @Override
    public List<User> listSecUsers() {
        /** 
        * @Description: 查出所有的用户信息，不分页
        * @Param: [] 
        * @return: java.util.List<cn.wsn2018.tools.model.User> 
        * @Author: SongDaisong 
        * @Date:  2020/1/21 18:20
        */
        Query query = new Query();
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        List<User> users = mongoTemplate.find(query, User.class, "user");
        return users;
    }

    @Override
    public List<User> listTemporarySecUsers() {
        /** 
        * @Description: 返回所有临时账户
        * @Param: [] 
        * @return: java.util.List<cn.wsn2018.tools.model.User> 
        * @Author: SongDaisong 
        * @Date:  2020/1/21 19:59
        */ 
        Query query = new Query();
        //查找临时账户 type为0
        query.addCriteria(Criteria.where("type").is(CommonValue.TYPE_TEMPORARY_0));
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        List<User> users = mongoTemplate.find(query, User.class, "user");
        return users;
    }

    @Override
    public boolean removeSecUserById(String id) {
        /**
         * @Description: 账户注销
         * @Param: [id]
         * @return: boolean
         * @Author: SongDaisong
         * @Date:  2020/1/21 20:08
         */
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = Update.update("state", CommonValue.STATE_DEL);
        //注销的用户变成未授权、未锁定 休眠时间，上次锁定时间都清空
        update.set("permission", CommonValue.NO_PERMISSION)
                .set("lock",CommonValue.USER_UNLOCK)
                .set("lastSleepTime","").set("lockedDateTime","");
        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
        return modifiedCount==1?true:false;
    }

    @Override
    public boolean sleepSecUserById(String id) {
        /** 
        * @Description: 账户休眠
        * @Param: [id] 
        * @return: boolean 
        * @Author: SongDaisong 
        * @Date:  2020/1/21 20:08
        */

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        //休眠状态
        Update update = Update.update("state",CommonValue.STATE_SLEEP);
        //重置锁定状态-----解锁 锁定时间清空
        update.set("lock",CommonValue.USER_UNLOCK).set("lockedDateTime","");
        //设置休眠时间
        update.set("lastSleepTime",DateUtil.dateToString(new Date()));
        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
        return true;
    }

    @Override
    public boolean activeSecUserById(String id) {
        /**
         * @Description: 账户激活
         * @Param: [id]
         * @return: boolean
         * @Author: SongDaisong
         * @Date:  2020/1/21 20:08
         */
        User secUserById = getSecUserById(id);
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = Update.update("state", CommonValue.STATE_ACTIVE);
        //休眠时间消除
        update.set("lastSleepTime","");
        //如果用户是临时账户，则还需要更新账号创建时间
        //因为临时账户有效期是做多90天。临时账户处于休眠，只可能是有账号效期到了
        //再次激活使用，相当于“重新”创建了一个同名账户
        if (CommonValue.TYPE_TEMPORARY_0.equals(secUserById.getType()))
            update.set("createTime",DateUtil.dateToString(new Date()));

        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
        return modifiedCount==1?true:false;
    }

    @Override
    public boolean lockSecUserById(String id) {
        /**
         * @Description: 账户锁定
         * @Param: [id]
         * @return: boolean
         * @Author: SongDaisong
         * @Date:  2020/1/21 20:08
         */
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));

        //设置账号锁定
        Update update = Update.update("lock", 1);
        //设置锁定的时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        update.set("lockedDateTime",sdf.format(date));

        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
        return modifiedCount==1?true:false;
    }

    @Override
    public boolean unlockSecUserById(String id) {
        /**
         * @Description: 账户解锁
         * @Param: [id]
         * @return: boolean
         * @Author: SongDaisong
         * @Date:  2020/1/21 20:08
         */
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = Update.update("lock", CommonValue.USER_UNLOCK);
        //锁定时间置为null
        update.set("lockedDateTime","");
        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
        return modifiedCount==1?true:false;
    }

    @Override
    public boolean givePermissionSecUserById(String id) {
        /** 
        * @Description: 用户授权 
        * @Param: [id] 
        * @return: boolean 
        * @Author: SongDaisong 
        * @Date:  2020/1/21 20:10
        */
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = Update.update("permission", CommonValue.HAS_PERMISSION);
        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
        return modifiedCount==1?true:false;
    }

    @Override
    public boolean askPermissionSecUserByName(String username) {
        /** 
        * @Description: 用户请求授权
        * @Param: [username] 
        * @return: boolean 
        * @Author: SongDaisong 
        * @Date:  2020/2/3 16:36
        */
        Query query = new Query();
        query.addCriteria(Criteria.where("username").is(username));
        Update update = new Update();
        update.set("permission",CommonValue.ASK_PERMISSION);
        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
        return modifiedCount==1?true:false;
    }

    @Override
    public boolean removePermissionSecUserById(String id) {
        /** 
        * @Description: 收回权限 
        * @Param: [id] 
        * @return: boolean 
        * @Author: SongDaisong 
        * @Date:  2020/1/21 20:10
        */ 
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = Update.update("permission", CommonValue.NO_PERMISSION);
        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
       // return modifiedCount==1?true:false;
        return true;
    }

    @Override
    public int resetSecUserPasswordByid(String id) throws UnsupportedEncodingException {
        /** 
        * @Description: 重置用户密码
        * @Param: [id] 
        * @return: int 
        * @Author: SongDaisong 
        * @Date:  2020/1/21 20:11
        */ 
        Query query=new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        User user = mongoTemplate.findOne(query,User.class,"user");
        if(user==null){
            System.out.println("用户不存在");
            return -1;
        }
        if(StringUtil.isEmptyString(user.getIdCard())){
            System.out.println("用户身份证信息不全");
            return 1;
        }
        //String idCard = user.getIdCard();

        Update update = Update.update("password", EncryptUtil.md5Encrypt(
                EncryptUtil.md5Encrypt(
                        "Wsn"+user.getIdCard().substring(
                user.getIdCard().length()-6,
                user.getIdCard().length())
                +"scuwsn")+(user.getUsername()+"wsn405").substring(0,7)));
                update.set("pwdUpdateTime",null);
        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
//        return modifiedCount==1?true:false;
        return 0;
    }

    @Override
    public boolean updateSecUserInfo(String id, String idCard, String phone, String role, Integer type, Integer accesssTime, String ipAddress) {
        /**
        * @Description:  根据id修改用户信息
        * @Param: [id, idCard, phone, role, type, accesssTime, ipAddress]
        * @return: boolean
        * @Author: SongDaisong
        * @Date:  2020/1/13 20:27
        */

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update();
        update.set("idCard",idCard).set("phone",phone).set("role",role).set("type",type).set("accessTime",accesssTime).set("ipAddress",ipAddress);
        User userById = getSecUserById(id);
        if (!role.equals(userById.getRole())){
            //如果用户角色改变了需要重新请求授权
            update.set("permission",CommonValue.NO_PERMISSION);
        }
        long modifiedCount = mongoTemplate.upsert(query, update, "user").getModifiedCount();
//      return modifiedCount==1?true:false;
        return true;
    }

    @Override
    public User getSecUserById(String id) {
        /**
        * @Description: 根据用户id查找用户
        * @Param: [id]
        * @return: cn.wsn2018.tools.model.User
        * @Author: SongDaisong
        * @Date:  2020/1/12 13:50
        */
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        User user = mongoTemplate.findOne(query, User.class, "user");
        user.setPassword(null);
        return user;
    }

    @Override
    public boolean setLastLoginTime(String id) {
        /** 
        * @Description: 更新用户的最近的登录时间
        * @Param: [id] 
        * @return: boolean 
        * @Author: SongDaisong 
        * @Date:  2020/1/28 16:41
        */ 
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update();
        update.set("lastTime", DateUtil.dateToString(new Date()));
        long modifiedCount = mongoTemplate.updateFirst(query, update, User.class, "user").getModifiedCount();
        return modifiedCount==1?true:false;
    }

    @Override
    public List<User> listLockedSecuser() {
        /** 
        * @Description: 查询所有处于锁定状态的用户 
        * @Param: []
        * @return: java.util.List<cn.wsn2018.tools.model.User> 
        * @Author: SongDaisong 
        * @Date:  2020/2/11 15:08
        */
        Query query = new Query();
        //查询处于锁定状态的用户
        query.addCriteria(Criteria.where("lock").is(CommonValue.USER_LOCK));
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        List<User> users = mongoTemplate.find(query, User.class, "user");

        return users;
    }

    @Override
    public List<User> listActiveSecuser() {
        /** 
        * @Description: 查询所有处于激活状态的用户
        * @Param: [] 
        * @return: java.util.List<cn.wsn2018.tools.model.User> 
        * @Author: SongDaisong 
        * @Date:  2020/2/11 15:19
        */
        Query query = new Query();
        query.addCriteria(Criteria.where("state").is(CommonValue.STATE_ACTIVE));
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        List<User> users = mongoTemplate.find(query, User.class, "user");
        return users;
    }


    @Override
    public List<User> listSleepSecuser() {
        /** 
        * @Description: 查询处于休眠状态的账户 
        * @Param: [] 
        * @return: java.util.List<cn.wsn2018.tools.model.User> 
        * @Author: SongDaisong 
        * @Date:  2020/3/25 21:16
        */
        Query query = new Query();
        //查询未注销的用户
        query.addCriteria(Criteria.where("state").is(CommonValue.STATE_SLEEP));
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        List<User> users = mongoTemplate.find(query, User.class, "user");
        return users;
    }

    @Override
    public Integer isHasSleepUserWillOverYear() {
        /** 
        * @Description:  是否有休眠账户即将一周内满一年
        * @Param: [] 
        * @return: java.lang.Integer 
        * @Author: SongDaisong 
        * @Date:  2020/3/27 14:54
        */
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        List<User> users = listSleepSecuser();

        int count=0;
        for (User u:users){
            String lastSleepTime = u.getLastSleepTime();
            //休眠的开始的时间
            LocalDateTime localDateTime = LocalDateTime.parse(lastSleepTime, fmt);
            //现在的时间
            LocalDateTime now = LocalDateTime.now();
            //现在的时间和休眠账户最大期间的时间差
            Duration duration = Duration.between(now, localDateTime.plusYears(1));
            long toDays = duration.toDays();
            if (toDays<=7){
                count++;
            }
        }
        return count;
    }

    /******************************************/

    static void conditionQuery(Query query,String role, String type, String state, String username,String lock,String permission){
        /** 
        * @Description: 封装的query条件添加
        * @Param: [query, role, type, state, username，lock，permission]
        * @return: void 
        * @Author: SongDaisong 
        * @Date:  2020/2/6 17:17
        */ 
        if(!StringUtil.isEmptyString(role)){
            //角色不为空
            query.addCriteria(Criteria.where("role").is(role));
        }

        if(!StringUtil.isEmptyString(type)){
            //类型不为空
            query.addCriteria(Criteria.where("type").is(Integer.parseInt(type)));
        }

        if(!StringUtil.isEmptyString(state)){
            //账号状态不为空
            query.addCriteria(Criteria.where("state").is(Integer.parseInt(state)));
        }
        if((!StringUtil.isEmptyString(username))){
            //用户名不为空
            query.addCriteria(Criteria.where("username").is(username));
        }
        if((!StringUtil.isEmptyString(lock))){
            //锁定状态不为空
            query.addCriteria(Criteria.where("lock").is(Integer.parseInt(lock)));
        }
        if((!StringUtil.isEmptyString(permission))){
            //授权状态不为空
            query.addCriteria(Criteria.where("permission").is(Integer.parseInt(permission)));
        }
    }


}
